package com.zyx.javademo.commons;

import org.apache.commons.cli.*;

import java.util.Optional;

/**
 * @author Yaxi.Zhang
 * @since 2021/8/10 13:37
 * desc: Apache Commons CLI是开源的命令行解析工具, 它可以帮助开发者快速构建启动命令, 并且帮助你组织命令的参数、以及输出列表等。
 *  CLI分为三个过程:
 *      定义阶段: 在Java代码中定义Optin参数，定义参数、是否需要输入值、简单的描述等
 *      解析阶段: 应用程序传入参数后，CLI进行解析
 *      询问阶段: 通过查询CommandLine询问进入到哪个程序分支中
 */
public class CommandDemo {
    public static void main(String[] args) {
        // String[] arg = {"-h", "-c", "config.xml"};
        testOptions(args);
    }

    public static void testOptions(String[] args) {
        getOptions();
        Options options = getOptions();

        HelpFormatter hf = new HelpFormatter();
        hf.setWidth(110);
        CommandLine commandLine;
        CommandLineParser parser = new DefaultParser();

        try {
            commandLine = parser.parse(options, args);
            if (commandLine.hasOption("h")) {
                // 打印使用帮助
                hf.printHelp("testApp", options, true);
            }

            // 打印opts的名称和值
            System.out.println("--------------------------------------");
            Option[] opts = commandLine.getOptions();
            if (opts != null) {
                for (Option opt : opts) {
                    String name = opt.getLongOpt();
                    String value = commandLine.getOptionValue(name);
                    System.out.println(name + "=>" + value);
                }
            }
        }
        catch (ParseException e) {
            hf.printHelp("testApp", options, true);
        }
    }

    private static Options getOptions() {
        /*
            其中Option的参数：
                第一个参数: 参数的简单形式, 通过 -xxx 传入
                第二个参数: 参数的复杂形式, 通过 --xxx 传入
                第三个参数: 是否需要额外的输入, 设置为false时及时 -xxx 或者 --xxx 后面跟了参数打印的参数仍然为null
                第四个参数: 对参数的描述信息
         */
        Options options = new Options();
        Option opt = new Option("h", "help", false, "Print help");
        opt.setRequired(false);
        options.addOption(opt);

        opt = new Option("c", "configFile", true, "Name server config properties file");
        opt.setRequired(false);
        options.addOption(opt);

        opt = new Option("p", "printConfigItem", false, "Print all config item");
        opt.setRequired(false);
        options.addOption(opt);

        return options;
    }

    public void parseOptions() {
        Options options = new Options();
        String[] args = {};
        CommandLine commandLine = null;
        CommandLineParser parser = new DefaultParser();
        try {
            // 通过解析器解析参数
            commandLine = parser.parse(options, args);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public void queryOptions() {
        HelpFormatter hf = new HelpFormatter();
        Options options = new Options();
        hf.setWidth(110);
        CommandLine commandLine = null;
        // 根据commandLine查询参数，提供服务
        if (commandLine.hasOption("h")) {
            // 打印使用帮助
            hf.printHelp("testApp", options, true);
        }
    }
}
